home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Communication / LibraryOfCongress / Source / ColorBars.m < prev    next >
Text File  |  1994-05-21  |  7KB  |  324 lines

  1. /*
  2.  * Magic Media Lab Colorbars, from the Media Lab letterhead,
  3.  * with some animation tricks.  c.f. License.m for an example of use.
  4.  */
  5.  
  6. /*
  7.     Copyright (c) 1991, 1992 by the MIT Media Laboratory
  8.     
  9.     This software is distributed by Michael Hawley of the MIT Media Laboratory. 
  10.     We hope it will be useful to you.
  11.     
  12.     Permission to use, copy, or modify this software for educational 
  13.     and research purposes only and without fee is hereby granted 
  14.     provided this notice appears on all copies, and provided you send 
  15.     us your improvements.  Any other use of this software, in original 
  16.     or modified form, in whole or in part, requires specific permission 
  17.     from MIT.  This software shall not be used, rewritten, or adapted 
  18.     for use in a commercial product without first obtaining appropriate 
  19.     licenses from MIT.  MIT makes no representations about the suitability 
  20.     of this software for any purpose: it is provided "as is" without any 
  21.     warranty and any risk, damage, or liability incurred through your use 
  22.     of this software is yours alone.
  23.     
  24.     Michael Hawley
  25.     MIT Media Laboratory
  26.     20 Ames Street, 
  27.     Cambridge, MA 02139
  28.     mike@media-lab.mit.edu
  29. */
  30. #import "ColorBars.h"
  31. #import <dpsclient/wraps.h>
  32.  
  33. @implementation ColorBars
  34.  
  35. extern usleep(), random(), bcopy();
  36.  
  37. #define N 8
  38.  
  39. static float pct[N] = { .0790, .1535, .0564, .2279, .0745, .2596, .1083, .0406};
  40. static NXColor color[N];
  41.  
  42. static void
  43. initColors(){
  44.     int i = 0;
  45. #define C(r,g,b) color[i++] = NXConvertRGBToColor(r / 256., g / 256., b / 256.);
  46.     C(77,17,93)
  47.     C(0,85,0)
  48.     C(255,255,255)
  49.     C(210,0,0)
  50.     C(255,90,0)
  51.     C(0,0,151)
  52.     C(255,248,0)
  53.     C(85,85,85)
  54. }
  55.  
  56. - initFrame:(NXRect *)r {
  57.     [super initFrame:r];
  58.     backgroundColor = NX_COLORWHITE;
  59.     delay = .25;
  60.     initColors();
  61.     return self;
  62. }
  63.  
  64. void
  65. drawColors(c,R) NXColor *c; NXRect R; {
  66.     int i;
  67.     NXCoord w = R.size.width;
  68.     NXRect r;
  69.     
  70.     r = R;
  71.     r.size.width = w * pct[0];
  72.  
  73.     for (i=0; i<N; i++, r.size.width = w * pct[i]){
  74.         NXSetColor(c[i]);
  75.         NXRectFill(&r);
  76.         r.origin.x += r.size.width;
  77.     }
  78. }
  79.  
  80. - drawColors:(NXColor *)c{
  81.     drawColors(c,bounds);
  82.     return self;
  83. }
  84.  
  85. - (int)running { return running; }
  86.  
  87. static NXColor
  88. fade(i,n,c1,c2)
  89.     int i, n;
  90.     NXColor c1, c2;
  91. /* return a color that's i/n of the way from c1->c2 in RGB */
  92. {
  93.     float r1, g1, b1, r2, g2, b2;
  94.     float p = (float)(i)/(float)(n-1);
  95.     NXConvertColorToRGB(c1,&r1,&g1,&b1);
  96.     NXConvertColorToRGB(c2,&r2,&g2,&b2);
  97. #define mix(a,b) (a-p*(a-b))
  98.     r1 = mix(r1,r2); g1 = mix(g1,g2); b1 = mix(b1,b2);
  99.     c1 = NXConvertRGBToColor(r1,g1,b1);
  100.     return c1;
  101. }
  102.  
  103. - fill:(NXColor)c {
  104.     NXSetColor(c);
  105.     NXRectFill(&bounds);
  106.     return self;
  107. }
  108.  
  109. - stop {
  110.     running = 0;
  111.     return self;
  112. }
  113.  
  114. - (NXColor)backgroundColor { return backgroundColor; }
  115. - setBackgroundColor:(NXColor)c {
  116.     backgroundColor = c;
  117.     return self;
  118. }
  119.  
  120. void
  121. swabScramble(n) int n[N]; {
  122.         int k=0,r,t[N] = {0,1,2,3,4,5,6,7};
  123. #define pick(t,n) t[r=random()%n]
  124. #define skip(t,n) { int i,j=0; for (i=0;i<N;i++){ t[j] = t[i]; if (t[j] != n) j++; } }
  125.     for (k=0;k<N;k++) n[k] = -1;
  126.     k = 0;
  127.     
  128.     skip(t,k);
  129.     n[k] = pick(t,7);
  130.     skip(t,n[k]);
  131.     n[n[k]] = k;
  132.     while (n[k] != -1 && k < N) k++;
  133.     
  134.     skip(t,k);
  135.     n[k] = pick(t,5);
  136.     skip(t,n[k]);
  137.     n[n[k]] = k;
  138.     while (n[k] != -1 && k < N) k++;
  139.     
  140.     skip(t,k);
  141.     n[k] = pick(t,3);
  142.     skip(t,n[k]);
  143.     n[n[k]] = k;
  144.     while (n[k] != -1 && k < N) k++;
  145.     
  146.     skip(t,k);
  147.     n[k] = pick(t,1);
  148.     skip(t,n[k]);
  149.     n[n[k]] = k;
  150.     while (n[k] != -1 && k < N) k++;
  151. }
  152.  
  153. void
  154. swabStep(DPSTimedEntry te, double timeNow, id self)
  155. /*
  156.  * Interpolate between pairs of segments
  157.  */
  158. {
  159.     static int i = 0, f = 0;
  160.     int j;
  161.     static NXColor pc[N], cc[N];
  162.     NXColor c[N];
  163. #define M 48
  164.  
  165.     if (i==0){ /* pick random pairs of colors */
  166.         int n[8];
  167.     if (f==0){
  168.         f = 1;
  169.         for (j=0;j<N;j++){
  170.             pc[j] = [self backgroundColor];
  171.             cc[j] = color[j];
  172.         }
  173.     } else {
  174.         if (f%3 == 0){
  175.             for (j=0;j<N;j++) cc[j] = color[j];
  176.         } else {
  177.             swabScramble(n);
  178.             for (j=0;j<N;j++) cc[j] = pc[n[j]];
  179.         }
  180.     }
  181.     }
  182.     
  183.     for (j=0;j<N;j++) c[j] = fade(i,M,pc[j],cc[j]);
  184.     [self lockFocus];
  185.     [self drawColors:c];
  186.     i++;
  187.     if (i==M || ![self running]){
  188.         i = 0;
  189.     if (![self running] && te) DPSRemoveTimedEntry(te);
  190.     for (j=0;j<N;j++) pc[j] = cc[j];
  191.     f++;
  192.     }
  193.     [self unlockFocus];
  194.     [[self window] flushWindow]; NXPing();
  195. }
  196.  
  197. void
  198. fadeStep(DPSTimedEntry te, double timeNow, id self) {
  199.     static int i = 0;
  200.     int j;
  201.     NXColor c[N];
  202. #undef M
  203. #define M 64
  204.     for (j=0;j<N;j++) c[j] = fade(i,M,[self backgroundColor],color[j]);
  205.     [self lockFocus];
  206.     [self drawColors:c];
  207.     i++;
  208.     if (i==M || ![self running]){
  209.         i = 0;
  210.     if (te) DPSRemoveTimedEntry(te);
  211.     [self stop];
  212.     }
  213.     [self unlockFocus];
  214.     [[self window] flushWindow]; NXPing();
  215. }
  216.  
  217. - fadeOn {
  218.     running = 1;
  219.     while (running) fadeStep(0,0.,self), usleep(2500);
  220.     return self;
  221. }
  222.  
  223. void
  224. scramble(n) int *n; {
  225.     int i, k, l, random();
  226.     for (i=0; i<N; i++) n[i] = i;
  227.     for (i=0; i<N; i++){
  228.         k = random()%N;
  229.     l = n[k];
  230.     n[k] = n[i];
  231.     n[i] = l;
  232.     }
  233. }
  234.  
  235. void
  236. scrambleStep(DPSTimedEntry te, double timeNow, id self) {
  237.     static int skip = 0;
  238.     int cn[N], j, random();
  239.     NXColor c[N];
  240.     
  241.     if (skip > 0) { skip--; return; }
  242.     [self lockFocus];
  243.     if (random()%8 == 3){
  244.     [self drawColors:color];
  245.     skip = 3;
  246.     } else {
  247.     scramble(cn);
  248.     for (j=0;j<N;j++) c[j] = color[cn[j]];
  249.     [self drawColors:c];
  250.     if (![self running]){
  251.         DPSRemoveTimedEntry(te);
  252.         [self stop];
  253.     }
  254.     }
  255.     [self unlockFocus];
  256.     [[self window] flushWindow]; NXPing();
  257. }
  258.  
  259. - winkOff {
  260.     NXRect r, a, b;
  261.     r = a = b = bounds;
  262.     drawColors(color,bounds); [window flushWindow]; NXPing();
  263.     NXSetColor(backgroundColor);
  264.     a.size.height = b.size.height = 1;
  265.     a.origin.y = r.origin.y + r.size.height;
  266.     while (a.origin.y > b.origin.y){
  267.         NXRectFill(&a); NXRectFill(&b);
  268.     a.origin.y -= 1;
  269.     b.origin.y += 1;
  270.     usleep(30000);
  271.     [window flushWindow]; NXPing();
  272.     }
  273.     a.origin.y += 1;
  274.     b.origin.y -= 1;
  275.     r = b; r.size.height = a.origin.y - b.origin.y;
  276.     while (r.size.width > 2){
  277.         NXSetColor(backgroundColor); NXRectFill(&r);
  278.     r.origin.x += 2; r.size.width -= 4;
  279.         drawColors(color,r); [window flushWindow]; NXPing();
  280.     }
  281.     r.size.width = 1;
  282.     NXSetColor(NXConvertRGBToColor(.05,.05,.05)); NXRectFill(&r);
  283.     [window flushWindow]; NXPing();
  284.     usleep(1000000);
  285.     NXSetColor(backgroundColor); NXRectFill(&r);
  286.     [window flushWindow]; NXPing();
  287.     usleep(300000);
  288.     return self;
  289. }
  290.  
  291. - setDrawstyle:(int)n {
  292.     style = n;
  293.     return [self display];
  294. }
  295.  
  296. - animate:(void (*)())f{
  297.     if (!running)
  298.         running++, DPSAddTimedEntry(0.025, f, self,100);
  299.     return self;
  300. }
  301.  
  302. - animate:(void (*)())f :(float)t{
  303.     if (!running)
  304.         running++, DPSAddTimedEntry(t, f, self,100);
  305.     return self;
  306. }
  307.  
  308. - drawSelf:(const NXRect *)rects :(int)n {
  309.     switch (style){
  310.     case PLAIN:     return [self drawColors:color];
  311.     case FADE:      return [self animate:fadeStep];
  312.     case SWAB:      return [self animate:swabStep];
  313.     case SCRAMBLE:  return [self animate:scrambleStep:delay];
  314.     case FSCRAMBLE: [self fadeOn];
  315.                     usleep(1000000);
  316.             return [self animate:scrambleStep:delay];
  317.     case CLEAR:     return [self fill:backgroundColor];
  318.     case WINKOFF:   return [self winkOff];
  319.     }
  320.     return self;
  321. }
  322.  
  323. @end
  324.